package com.shujia.scala

object Demo06Func02 {
  def main(args: Array[String]): Unit = {

    /**
     * 面向对象编程：
     * 将对象作为某个方法的 参数 或者是 返回值 传来传去 ，在传递时需要考虑类型的限制
     * 函数式编程（高阶函数、面向函数编程）：
     * 将函数作为某个方法的 参数 或者是 返回值 传来传去 ，在传递时也需要考虑类型的限制
     * 函数的类型如何确定？ （排除法）
     * 1、和def关键字无关
     * 2、和函数名无关
     * 3、和函数体无关
     * 4、和参数名无关
     * 结论：函数的类型 和参数的类型、数量以及返回值的类型 有关
     *
     * 如何描述函数的类型？
     *    如果参数只有一个，则括号可以省略
     *    (参数1的类型,参数2的类型......)=>返回值的类型
     * 函数式编程分类：
     *  1、以函数作为参数（必须熟练掌握，经常结合匿名函数一起搭配使用）
     *  2、以函数作为返回值（了解）
     *
     */

    // String => Int
    def f1(s: String): Int = {
      s.toInt + 100
    }

    // String => Int
    def f2(s: String): Int = {
      s.toInt + 200
    }

    // Int => Int
    def f3(i: Int): Int = {
      i + 100
    }

    // String => String
    def f4(s: String): String = {
      s + "100"
    }

    // String => Int
    def f5(str: String): Int = {
      str.toInt + 100
    }

    // 函数式编程之以函数作为参数
    def funcX1(f:String => Int):Int = {
      val fRes: Int = f("123")
      fRes+100
    }

    // 省略写法
    def funcX2(f:String => Int)= f("123") + 100

    println(funcX1(f1)) // 323
    println(funcX1(f2)) // 423
//    funcX1(f3)
//    funcX1(f4)
    println(funcX1(f5)) // 323

    println(funcX2(f1))
    println(funcX2(f2))
    println(funcX2(f5))
  }
}
